home *** CD-ROM | disk | FTP | other *** search
- /* Written 9:30 am Jul 26, 1986 by dubois@uwmacc.UUCP in uiucdcsb:mod.mac.sources */
- Here is the LightspeedC source to ZoomIdle1.1. For printing, tab
- size should be 4.
- --- cut ---
- /*
- ZoomIdle
- Version 1.1 25 July 1986
-
- Screen saver desk accessory. Generates successive randomly chosen
- rectangles, and zooms each into the next by interpolating a series
- of rectangles intermediate in shape and location. Click and hold in
- menu bar to pause the display. Click below menu bar to terminate.
-
- The project should include MacTraps and ZoomIdle1.1.c. The project
- type should be Desk Accessory.
-
- Changes since 1.0:
-
- Works with Macintosh XL (wider screen).
- Doesn't clear the menu bar until the window receives an activate
- event. 1.0 cleared the bar immediately, which was too early -
- some programs would crash when ZoomIdle exited.
-
-
- Paul DuBois
- Wisconsin Regional Primate Research Center
- 1220 Capitol Court
- University of Wisconsin-Madison
- Madison, WI 53706
-
- UUCP: {allegra, ihnp4, seismo}!uwvax!uwmacc!dubois
- ARPA: dubois@easter
- dubois@unix.macc.wisc.edu
- */
-
-
- # include <DeviceMgr.h>
- # include <WindowMgr.h> /* includes QuickDraw.h, MacTypes.h */
- # include <EventMgr.h>
- # include <MenuMgr.h>
-
- # define nil 0L
-
-
- /*
- zoomSteps controls the number of rectangles that are drawn in each
- interpolative series. zoomShow controls how many rectangles are
- visible at once. These two values may be varied independently, but
- they must both be greater than zero.
- */
-
- # define zoomSteps 15
- # define zoomShow 15
-
-
- /* global variables */
-
- Rect zRect[zoomShow];
- int zIndex;
-
-
- /*
- Return integer between zero and max (inclusive). Assumes max is
- non-negative.
- */
-
-
- Rand (max)
- int max;
- {
- register int t;
-
- if ((t = Random ()) < 0) t = -t;
- return (t % (max + 1));
- }
-
-
- /*
- Interpolate one rectangle smoothly into another. This algorithm
- assumes that it is erasing the previous series while it's
- drawing the new one. The first time this is called, that is not
- true, which is why the init code sets all the zRect rectangles
- empty - it's harmless to erase empty rectangles (doesn't show on
- screen).
-
- Pen mode should be set to patXor, so that the first drawing shows
- the rectangle, the second time erases it. Gray seems to work
- best for the pen pattern: white is too stark a contrast, except
- perhaps for the very dialectic.
- */
-
- ZoomRect (r1, r2)
- Rect r1, r2;
-
- {
- register int r1left, r1top;
- register int l, t;
- register int j;
- int hDiff, vDiff, widDiff, htDiff;
- int r, b;
- int rWid, rHt;
- register Rect *rp;
-
- r1left = r1.left;
- r1top = r1.top;
- hDiff = r2.left - r1left; /* positive if moving to right */
- vDiff = r2.top - r1top; /* positive if moving down */
- rWid = r1.right - r1left;
- rHt = r1.bottom - r1top;
- widDiff = (r2.right - r2.left) - rWid;
- htDiff = (r2.bottom - r2.top) - rHt;
-
- /*
- order of evaluation is important in the rect coordinate calculations.
- since all arithmetic is integer, you can't save time by calculating
- j/zoomSteps and using that - it'll usually be zero.
- */
-
- for (j = 1; j <= zoomSteps; j++)
- {
- if (++zIndex >= zoomShow)
- zIndex = 0;
- rp = &zRect[zIndex];
- FrameRect (rp); /* erase a rectangle */
- l = r1left + (hDiff * j) / zoomSteps;
- t = r1top + (vDiff * j) / zoomSteps;
- r = l + rWid + (widDiff * j) / zoomSteps;
- b = t + rHt + (htDiff * j) / zoomSteps;
- SetRect (rp, l, t, r, b);
- FrameRect (rp);
- }
-
- }
-
-
- main(p, d, n)
- cntrlParam *p; /* ==> parameter block */
- DCtlPtr d; /* ==> device control entry */
- int n; /* entry point selector */
-
- {
- register DCtlPtr dce = d;
- Rect dstRect;
- Point pt1, pt2;
- long pat[2];
- static int scrnSizeX;
- static int scrnSizeY;
- static Rect srcRect;
- static Handle theMenuBar;
- static WindowPtr theWind;
- static Boolean zoomAway = false;
-
-
- /* check to make sure our data area was allocated */
-
- if (dce->dCtlStorage == 0)
- {
- if (n == 0) /* open */
- CloseDriver(dce->dCtlRefNum);
- }
- else switch (n) /* dispatch */
- {
- case 0: /* open */
-
- dce->dCtlFlags |= dNeedLock | dNeedTime;
- dce->dCtlDelay = 0;
- dce->dCtlEMask = everyEvent;
-
- GetWMgrPort (&theWind);
- srcRect = theWind->portRect;
- scrnSizeX = srcRect.right; /* get size of screen */
- scrnSizeY = srcRect.bottom;
- theWind = NewWindow (nil, &srcRect, "\p", true,
- noGrowDocProc, -1L, true, 0L);
- RectRgn (theWind->visRgn, &srcRect);
- ((WindowPeek) theWind)->windowKind = dce->dCtlRefNum;
-
- /*
- Initialize the rect array. This also sets zIndex
- to a value that causes it to reset to zero on the
- first call to ZoomRect.
- */
- for (zIndex = 0; zIndex < zoomShow; ++zIndex)
- SetRect (&zRect[zIndex], 0, 0, 0, 0);
-
- break;
-
- case 2: /* control */
-
- SetPort (theWind);
- switch (p->csCode)
- {
- case accEvent: /* put glasses on to read next switch */
-
- switch (((EventRecord *) * (long *) &p->csParam)->what)
- {
- case activateEvt:
-
- theMenuBar = GetMenuBar ();
- ClearMenuBar ();
- PaintRect (&srcRect /* = &theWind->portRect */);
- PenMode (patXor); /* do all drawing in xor */
- pat[0] = pat[1] = 0xaa55aa55L;
- PenPat (&pat); /* can't use QD global pats! */
- zoomAway = true;
- break;
-
- case mouseDown: /* quit on mousedown event */
-
- CloseDriver(dce->dCtlRefNum);
- break;
- }
- break;
-
- case accRun:
-
- if (zoomAway) /* activated */
- {
- ObscureCursor (); /* keep cursor hidden */
- pt1.h = Rand (scrnSizeX); /* generate rect and zoom to it */
- pt1.v = Rand (scrnSizeY);
- pt2.h = Rand (scrnSizeX);
- pt2.v = Rand (scrnSizeY);
- Pt2Rect (pt1, pt2, &dstRect);
- ZoomRect (srcRect, dstRect);
- srcRect = dstRect;
- }
- break;
- }
- break;
-
- case 4: /* close */
-
- DisposeWindow (theWind);
- SetMenuBar (theMenuBar); /* restore menu bar */
- DisposHandle (theMenuBar);
- DrawMenuBar ();
- break;
- }
-
- /* done */
-
- return(0);
- }
- --- end ---
- /* End of text from uiucdcsb:mod.mac.sources */
-